// 类型推断infer  类型保护  兼容性  装包拆包  装饰器

function sum(a: string, b: string) {
  return { a, b };
}
// 1.推断函数的返回值类型
// 类型是在ts中使用的 值是在js中使用的

interface X {
  (): void;
}
// type ReturnType<F extends (...args:any[])=>any> = F extends (...args:any[])=> infer R ? R: any; // 三元 条件
type MyReturnType = ReturnType<typeof sum>; // 取函数的返回值类型

// sum函数的参数 =》 [a:string,b:string]

type Parameters<F extends (...args: any[]) => any> = F extends (
  ...args: infer R
) => any
  ? R
  : any;
type MyParameters = Parameters<typeof sum>;

class Animal {
  constructor(a: string, b: string, c: number) {}
}

type ConstructorParameters<C extends new (...args: any[]) => any> =
  C extends new (...args: infer R) => any ? R : any;
type MyConstrcutorParams = ConstructorParameters<typeof Animal>;

type InstanceType<C extends new (...args: any[]) => any> = C extends new (
  ...args: any[]
) => infer R
  ? R
  : any;
type MyinstanceType = InstanceType<typeof Animal>;

// infer 就是可以根据代码的位置来推断结果   ReturnType

// node -> webpack  （每个阶段是一个半月）
// vite -》 vue3 + ts实战 -》 vue3源码

// unkown类型 用来取代any的  any是否安全呢？

let a: unknown = 1; // 我们尽量不要标识any 会导致后续的调用出错，如果你只是不知道他的类型，那么你就不要写any 写 unkown ，unkown是any的安全类型

// 任何类型都可以赋予给unkown
// unkown 不能使用

type r1 = unknown | string; // 并集  -》 还是不知道是什么东西
type r2 = unknown & string; // 交叉类型  任何类型和unknown 相交 都是其他类型

type r3 = keyof unknown; // keyof any 可以出现string  number  symbol  keyof unkown=》 never

// never 是unkown的子类型
// type r4 = never extends unknown ? true:false

type xxx = {
  a: 1;
};
type ttt = {
  b: 2;
};
type Compute<T> = {[P in keyof T]:T[P]}
type ooo = Compute<xxx & ttt>
export {};
